﻿using System;
using System.Collections.Generic;
using System.Data;
using FamilyBook.Core;
using FamilyBook.Core.Exceptions;
using FamilyBook.Core.Repositories;

namespace FamilyBook.Repository.EF
{
    public class GeneralRepository<TEntity, TEntityId> : IGeneralRepository<TEntity, TEntityId> where TEntity : class
    {
        private readonly FamilyBookDbContext _dbContext;

        public GeneralRepository(IDbSession dbSession)
        {
            if (dbSession == null)
                throw new ArgumentNullException("dbSession");

            _dbContext = (FamilyBookDbContext)dbSession.DbContext;
        }

        public object DbContext { get { return _dbContext; } }

        public TEntity Create(TEntity entityInstance)
        {
            _dbContext.Entry<TEntity>(entityInstance).State = EntityState.Added;
            _dbContext.SaveChanges();
            return entityInstance;
        }
        public TEntity Read(TEntityId entityId)
        {
            TEntity obj = _dbContext.Set<TEntity>().Find(entityId);
            if (obj == null)
                throw new RepositoryNotFoundException(string.Format("{0} ID:{1} does not exist", typeof(TEntity).Name, entityId));

            return obj;
        }
        public bool TryRead(TEntityId entityId, out TEntity entityInstance)
        {
            entityInstance = _dbContext.Set<TEntity>().Find(entityId);
            return (entityInstance != null);
        }
        public IEnumerable<TEntity> ReadAll()
        {
            return _dbContext.Set<TEntity>();
        }
        public void Update(TEntity entityInstance)
        {
            _dbContext.Entry<TEntity>(entityInstance).State = EntityState.Modified;
            _dbContext.SaveChanges();
        }
        public void Delete(TEntity entityInstance)
        {
            _dbContext.Entry<TEntity>(entityInstance).State = EntityState.Deleted;
            _dbContext.SaveChanges();
        }
        public void Delete(TEntityId entityId)
        {
            TEntity obj = _dbContext.Set<TEntity>().Find(entityId);
            if (obj != null)
                Delete(obj);
        }
    }
}
